from typing import Type, List, TypeVar, Sequence

from pydantic import BaseModel

from app.models.base_model import Base

T = TypeVar('T', bound=Base)
P = TypeVar('P', bound=BaseModel)


def pydantic_to_model(source: BaseModel, target_class: Type[T]) -> T:
    """
    将 Pydantic 模型对象转换为 SQLAlchemy 模型对象

    :param source: 源 Pydantic 模型对象
    :param target_class: 目标 SQLAlchemy 模型类
    :return: 转换后的 SQLAlchemy 模型对象，类型为target_class的具体实例
    :raises ValueError: 当转换失败时抛出异常
    """
    try:
        return target_class(**source.model_dump())
    except Exception as e:
        raise ValueError(f"无法将 Pydantic 模型转换为 {target_class.__name__}: {e}")


def model_to_pydantic(source: Base, target_class: Type[P]) -> P:
    """
   将 SQLAlchemy 模型对象转换为 Pydantic 模型对象

   :param source: 源 SQLAlchemy 模型对象
   :param target_class: 目标 Pydantic 模型类
   :return: 转换后的 Pydantic 模型对象，类型为target_class的具体实例
   :raises ValueError: 当转换失败时抛出异常
   """
    try:
        return target_class(**source.__dict__)
    except Exception as e:
        raise ValueError(f"无法将 {source.__class__.__name__} 转换为 Pydantic 模型: {e}")


def models_to_pydantic(source_list: List[T] | Sequence[T], target_class: Type[P]) -> List[P]:
    """
    将 SQLAlchemy 模型对象列表转换为 Pydantic 模型对象列表

    :param source_list: 源 SQLAlchemy 模型对象列表
    :param target_class: 目标 Pydantic 模型类
    :return: 转换后的 Pydantic 模型对象列表
    :raises ValueError: 当转换失败时抛出异常
    """
    try:
        return [model_to_pydantic(source, target_class) for source in source_list]
    except Exception as e:
        raise ValueError(f"无法将 {source_list[0].__class__.__name__} 列表转换为 Pydantic 模型列表: {e}")
